package de.openkanban.client.ui.board;

import com.google.gwt.http.client.RequestCallback;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.AnimationEffect;
import com.smartgwt.client.types.BkgndRepeat;
import com.smartgwt.client.widgets.AnimationCallback;
import com.smartgwt.client.widgets.IButton;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.events.DoubleClickEvent;
import com.smartgwt.client.widgets.events.DoubleClickHandler;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.TextItem;
import com.smartgwt.client.widgets.form.fields.events.KeyPressEvent;
import com.smartgwt.client.widgets.form.fields.events.KeyPressHandler;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.Layout;
import com.smartgwt.client.widgets.layout.VLayout;

import de.openkanban.client.login.LogIn;
import de.openkanban.client.ui.presenter.PreparedRequest;
import de.openkanban.client.ui.presenter.SwitchBoardRequestCallback;
import de.openkanban.client.ui.presenter.UpdateBoardRequestCallback;
import de.openkanban.client.util.RootPanel;
import de.openkanban.shared.dto.BoardDto;

/**
 * GUI Element for the BoardView
 */
public class BoardView extends VLayout {
	private static final int BOARD_NAME_MIN_WIDTH = 150;
	private Label currentBoardNameLabel;
	private DynamicForm currentBoardNameForm;
	private TextItem currentBoardNameTextItem;

	private IButton newActivityButton;
	private IButton newKanbanButton;
	private IButton nextBoardButton;
	private IButton prioBoardButton;

	private HLayout boardHeaderHLayout;
	private Layout boardHeaderLeftLayout;
	private Layout boardHeaderMiddleLayout;
	private HLayout boardHeaderRightHLayout;
	private Layout boardHeaderSwitchLayout;

	private HLayout greyBackground;
	private VLayout kanbanLayout;

	private WhiteBoardView whiteBoardView;
	private KanbanEditView kanbanEditView;

	private RequestCallback switchBoardRequestCallback;
	private boolean footerWasOpenFlag;
	private HLayout kanbanHLayout;
	private Layout border1;
	private Layout border2;

	public BoardView() {
		whiteBoardView = new WhiteBoardView();

		switchBoardRequestCallback = new SwitchBoardRequestCallback(this);

		newActivityButton = new BoardHeaderButton("+ activity");
		newActivityButton.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				newActivityButton.setDisabled(true);
				ActivityView activityView = new ActivityView(whiteBoardView.getBoardDto().getBoardId());
				whiteBoardView.addActivity(activityView);
			}
		});

		newKanbanButton = new BoardHeaderButton("+ kanban");
		newKanbanButton.setVisible(false);
		newKanbanButton.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				RootPanel.activateEditKanbanMode(true);
			}
		});

		prioBoardButton = new BoardHeaderButton("<<");

		prioBoardButton.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				PreparedRequest prepReq = new PreparedRequest("board", whiteBoardView.getBoardDto().getBoardId().toString()
						+ "/" + LogIn.getUserDto().getUserId().toString() + "/backward");
				prepReq.sendAsyncRequest(switchBoardRequestCallback);
			}
		});

		nextBoardButton = new BoardHeaderButton(">>");

		nextBoardButton.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				PreparedRequest prepReq = new PreparedRequest("board", whiteBoardView.getBoardDto().getBoardId().toString()
						+ "/" + LogIn.getUserDto().getUserId().toString() + "/forward");
				prepReq.sendAsyncRequest(switchBoardRequestCallback);
			}
		});

		boardHeaderHLayout = new HLayout();
		boardHeaderHLayout.setHeight(40);
		boardHeaderHLayout.setVisible(false);

		currentBoardNameLabel = new Label();
		currentBoardNameLabel.setWrap(false);
		currentBoardNameLabel.setStyleName("boardNameLabel");
		currentBoardNameLabel.setMinWidth(BOARD_NAME_MIN_WIDTH);
		currentBoardNameLabel.setAlign(Alignment.CENTER);
		currentBoardNameLabel.addDoubleClickHandler(boardNameLabelDoubleClickHandler());

		currentBoardNameTextItem = new TextItem();
		currentBoardNameTextItem.setShowTitle(false);
		currentBoardNameTextItem.setHeight(30);
		currentBoardNameTextItem.setWidth(BOARD_NAME_MIN_WIDTH);
		currentBoardNameTextItem.setTextBoxStyle("boardNameTextItem");
		currentBoardNameTextItem.setShowFocused(true);
		currentBoardNameTextItem.addKeyPressHandler(updateBoardNameKeyPressedHandler());

		currentBoardNameForm = new DynamicForm();
		currentBoardNameForm.setFields(currentBoardNameTextItem);

		// /////////////////////////////////////////////////////
		// BoardHeader
		// /////////////////////////////////////////////////////
		Layout leftMargin = new Layout();
		Layout rightMargin = new Layout();
		leftMargin.setWidth(10);
		rightMargin.setWidth(10);

		boardHeaderLeftLayout = new Layout();
		boardHeaderLeftLayout.setAutoWidth();
		boardHeaderLeftLayout.setBackgroundImage("boardheader/boardheader_left.png");
		boardHeaderLeftLayout.setBackgroundRepeat(BkgndRepeat.REPEAT_X);
		boardHeaderLeftLayout.addMember(leftMargin);
		boardHeaderLeftLayout.addMember(currentBoardNameLabel);

		boardHeaderMiddleLayout = new Layout();
		boardHeaderMiddleLayout.setWidth(55);
		boardHeaderMiddleLayout.setBackgroundImage("boardheader/boardheader_middle.png");

		boardHeaderRightHLayout = new HLayout();
		boardHeaderRightHLayout.setWidth("*");
		boardHeaderRightHLayout.setStyleName("boardHeaderLayout");
		boardHeaderRightHLayout.setBackgroundImage("boardheader/boardheader_right.png");
		boardHeaderRightHLayout.setBackgroundRepeat(BkgndRepeat.REPEAT_X);
		boardHeaderRightHLayout.addMember(newActivityButton);
		boardHeaderRightHLayout.addMember(newKanbanButton);

		boardHeaderSwitchLayout = new Layout();
		boardHeaderSwitchLayout.setStyleName("boardHeaderLayout");
		boardHeaderSwitchLayout.setAutoWidth();
		boardHeaderSwitchLayout.setBackgroundImage("boardheader/boardheader_right.png");
		boardHeaderSwitchLayout.setBackgroundRepeat(BkgndRepeat.REPEAT_X);
		boardHeaderSwitchLayout.addMember(prioBoardButton);
		boardHeaderSwitchLayout.addMember(nextBoardButton);
		boardHeaderSwitchLayout.addMember(rightMargin);

		boardHeaderHLayout.setHeight(57);
		boardHeaderHLayout.addMember(boardHeaderLeftLayout);
		boardHeaderHLayout.addMember(boardHeaderMiddleLayout);
		boardHeaderHLayout.addMember(boardHeaderRightHLayout);
		boardHeaderHLayout.addMember(boardHeaderSwitchLayout);

		// /////////////////////////////////////////////////////
		// KanbanEditMode
		// /////////////////////////////////////////////////////
		greyBackground = new HLayout();
		greyBackground.setBackgroundColor("#000000");
		greyBackground.setOpacity(70);
		greyBackground.setWidth100();
		greyBackground.setHeight100();
		greyBackground.setVisible(false);

		kanbanHLayout = new HLayout();
		kanbanHLayout.setWidth100();
		kanbanHLayout.setAlign(Alignment.CENTER);

		kanbanEditView = new KanbanEditView();
		Layout borderL = new Layout();
		borderL.setWidth("*");
		Layout borderR = new Layout();
		borderR.setWidth("*");

		kanbanHLayout.addMember(borderL);
		kanbanHLayout.addMember(kanbanEditView);
		kanbanHLayout.addMember(borderR);

		border1 = new Layout();
		border1.setHeight("*");
		border2 = new Layout();
		border2.setHeight("*");

		kanbanLayout = new VLayout();
		kanbanLayout.setWidth100();
		kanbanLayout.setHeight100();
		kanbanLayout.setAlign(Alignment.CENTER);
		kanbanLayout.setVisible(false);

		kanbanLayout.addMember(border1);
		kanbanLayout.addMember(kanbanHLayout);
		kanbanLayout.addMember(border2);

		addMember(boardHeaderHLayout);
		addMember(whiteBoardView);

		addChild(greyBackground);
		addChild(kanbanLayout);
	}

	private KeyPressHandler updateBoardNameKeyPressedHandler() {
		return new KeyPressHandler() {
			@Override
			public void onKeyPress(KeyPressEvent event) {
				if ("Enter".equals(event.getKeyName())) {
					updateBoardName(currentBoardNameTextItem.getValueAsString());
				}
			}
		};
	}

	public void updateBoardName(String boardName) {
		currentBoardNameLabel.setContents(boardName);
		whiteBoardView.getBoardDto().setBoardName(boardName);
		showCurrentBoardNameLabel();
		PreparedRequest prepReq = new PreparedRequest("board", "update", whiteBoardView.getBoardDto());
		prepReq.sendAsyncRequest(new UpdateBoardRequestCallback());
	}

	public void createBoardName(String boardName) {
		currentBoardNameLabel.setContents(boardName);
		BoardDto newBoardDto = new BoardDto();
		newBoardDto.setBoardName(boardName);

		showCurrentBoardNameLabel();

		PreparedRequest prepReq = new PreparedRequest("board", "create", newBoardDto);
		prepReq.sendAsyncRequest(new UpdateBoardRequestCallback());
	}

	private DoubleClickHandler boardNameLabelDoubleClickHandler() {
		return new DoubleClickHandler() {
			@Override
			public void onDoubleClick(DoubleClickEvent event) {
				currentBoardNameTextItem.setValue(currentBoardNameLabel.getContents());

				showCurrentBoardNameForm();
			}
		};
	}

	public void showCurrentBoardNameForm() {
		if (!boardHeaderLeftLayout.contains(currentBoardNameForm)) {
			boardHeaderLeftLayout.removeMember(currentBoardNameLabel);
			boardHeaderLeftLayout.addMember(currentBoardNameForm, 1);
		}
	}

	public void showCurrentBoardNameLabel() {
		if (!boardHeaderLeftLayout.contains(currentBoardNameLabel)) {
			boardHeaderLeftLayout.removeMember(currentBoardNameForm);
			boardHeaderLeftLayout.addMember(currentBoardNameLabel, 1);
		}
	}

	public void setKanbanEditMode(boolean isEdit) {
		if (isEdit) {
			kanbanEditView.clear();
			showEditKanbanMode();
		} else {
			hideEditKanbanMode();
		}
	}

	public void setKanbanEditMode(boolean isEdit, KanbanView kanbanView) {
		if (isEdit) {
			kanbanEditView.loadKanban(kanbanView);
		}
		showEditKanbanMode();
	}

	private void hideEditKanbanMode() {
		if (!footerWasOpenFlag) {
			kanbanLayout.animateHide(AnimationEffect.FLY, new AnimationCallback() {
				@Override
				public void execute(boolean earlyFinish) {
					RootPanel.main.getFooter().getFooterPanel().closeFooter(new AnimationCallback() {
						@Override
						public void execute(boolean earlyFinish) {
							greyBackground.animateHide(AnimationEffect.FADE, null, 500);
						}
					});
				}
			}, 1000);
		} else {
			kanbanLayout.animateHide(AnimationEffect.FLY, new AnimationCallback() {
				@Override
				public void execute(boolean earlyFinish) {
					greyBackground.animateHide(AnimationEffect.FADE, null, 500);
				}
			}, 1000);
		}
	}

	private void showEditKanbanMode() {
		footerWasOpenFlag = RootPanel.main.getFooter().getFooterPanel().isOpened();
		kanbanEditView.setParentActivityId(whiteBoardView.getFirstActicityDto().getActivityId());
		if (!footerWasOpenFlag) {
			RootPanel.main.getFooter().getFooterPanel().openFooter(new AnimationCallback() {
				@Override
				public void execute(boolean earlyFinish) {
					greyBackground.animateShow(AnimationEffect.FADE, new AnimationCallback() {
						@Override
						public void execute(boolean earlyFinish) {
							kanbanLayout.animateShow(AnimationEffect.FADE, null, 500);
						};
					}, 500);
				}
			});
		} else {
			greyBackground.animateShow(AnimationEffect.FADE, new AnimationCallback() {
				@Override
				public void execute(boolean earlyFinish) {
					kanbanLayout.animateShow(AnimationEffect.FADE, null, 500);
				};
			}, 500);
		}
	}

	public void enableNewActivityButton() {
		newActivityButton.setDisabled(false);
	}

	public void showNewKanbanButton() {
		newKanbanButton.setVisible(true);
	}

	public void hideNewKanbanButton() {
		newKanbanButton.setVisible(false);
	}

	public Label getCurrentBoardNameLabel() {
		return currentBoardNameLabel;
	}

	public IButton getNewActivityButton() {
		return newActivityButton;
	}

	public TextItem getCurrentBoardNameTextItem() {
		return currentBoardNameTextItem;
	}

	public HLayout getBoardHeaderHLayout() {
		return boardHeaderHLayout;
	}

	public WhiteBoardView getWhiteBoardView() {
		return whiteBoardView;
	}

	public IButton getNewKanbanButton() {
		return newKanbanButton;
	}

}
